/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package at.ofai.gate.riplugin2;

import com.google.common.io.Files;
import gate.Resource;
import gate.creole.ResourceInstantiationException;
import gate.creole.metadata.CreoleParameter;
import gate.creole.metadata.Optional;
import gate.event.CreoleEvent;
import gate.event.CreoleListener;
import gate.gui.ActionsPublisher;
import gate.util.GateRuntimeException;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import javax.swing.AbstractAction;

/**
 * A LR representing a SV random index. A SV random index is backed by
 * a directory that contains a Lucene index and the files for a positional
 * or non-positional SV random index. However, a LR can also just represent
 * an empty directory which will be the destination of a random index that
 * will still be created.
 * 
 * @author Johann Petrak
 */
public class RIIndexSVLR
  extends RIIndexLR
  implements ActionsPublisher, CreoleListener{

  @Optional
  @CreoleParameter(
    comment="Directory that should contain the random index data",
    defaultValue = "")
  /**
   * Set the URL of the directory that contains the random index data or
   * should contain the random index data (if it is still to be created).
   */
  public void setDirectoryURL(URL directoryURL) {
    this.directoryURL = directoryURL;
  }
  public URL getDirectoryURL() {
    return directoryURL;
  }
  protected URL directoryURL;

  // Fields and their getters
  protected File luceneIndexDir = null;
  public File getLuceneIndexDir() { return luceneIndexDir; }

  protected File svDocumentIndex = null;
  public File getSVDocumentIndex() { return svDocumentIndex; }

  protected File svTermIndex = null;
  public File getSVTermIndex() { return svTermIndex; }

  // FIELDS
  protected SVIndex svIndex = null;


  @Override
  public Resource init() throws ResourceInstantiationException {
    if(getDirectoryURL() == null || getDirectoryURL().equals("")) {
      try {
        directoryURL = createTmpDir();
      } catch (MalformedURLException ex) {
        throw new ResourceInstantiationException(
                "Could not create a tempory directory",ex);
      }
    }
    // check the directory and see if we have index files in there.
    // set the internal flags accordingly.
    File directory = gate.util.Files.fileFromURL(directoryURL);
    if(!directory.exists()) {
      throw new ResourceInstantiationException(
              "No directory exists with URL: "+directoryURL);
    }
    luceneIndexDir = new File(directory,"index");
    return this;
  }
  
  protected URL createTmpDir() throws MalformedURLException {
    URL dirUrl = null;
    // Once we require java 1.7 or greater, we can do this:
    //File tmpDirPath = Files.createTempDirectory("GATE_RIIndexSVLR_");
    File tmpDirPath = Files.createTempDir();
    dirUrl = tmpDirPath.toURI().toURL();
    return dirUrl;
  }

  public boolean open() {
    if(!hasData()) {
      return false;
    }
    if(svIndex != null) {
      close();
    }
    try {
      // determine if we do have a lucene dir too
      String luceneDir = null;
      if(getLuceneIndexDir().exists()) {
        luceneDir = getLuceneIndexDir().getCanonicalPath();
      }
      String docVecs = null;
      if(svDocumentIndex.exists()) {
        docVecs = svDocumentIndex.getCanonicalPath();
      }
      svIndex = new SVIndex(getSVTermIndex().getCanonicalPath(), docVecs, luceneDir);
    } catch (Exception ex) {
      throw new GateRuntimeException("Exception when opening SV Index: "+getDirectoryURL(),ex);
    }
    return true;
  }

  public void close() {
    svIndex = null;
  }

  public boolean isOpen() {
    return (svIndex != null);
  }

  public boolean hasData() {
    if(getSVTermIndex().exists()) {
      return true;
    } else {
      return false;
    }
  }
  

  public SVIndex getSVIndex() {
    return svIndex;
  }


  // implement ActionsPublisher methods
  protected List<AbstractAction> actionsList;
  public List getActions() {
    return actionsList;
  }

  // ************ Creole Listener Methods ************
  public void resourceLoaded(CreoleEvent ce) {
    // do nothing
  }

  public void datastoreClosed(CreoleEvent ce) {
  }

  public void resourceRenamed(Resource resource, String oldname, String newname) {
  }

  public void datastoreOpened(CreoleEvent ce) {
  }

  public void datastoreCreated(CreoleEvent ce) {
  }

  public void resourceUnloaded(CreoleEvent ce) {
  }

}
